package br.ufrj.dcc.ad.args;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;

import br.ufrj.dcc.ad.enums.DistributionType;
import br.ufrj.dcc.ad.enums.ExecutionType;
import br.ufrj.dcc.ad.enums.QueueType;
import br.ufrj.dcc.ad.enums.ServerType;
import br.ufrj.dcc.ad.generators.TimeGenerator;

public class ParametrosSimulacao {
	/** Número de iterações da aplicação. */
	private static int numeroIteracoes;
	/** Tipo de execução da simulação. */
	private static ExecutionType tipoExecucao;
	/** Será sempre exponencial. (Período entre chegadas). */
	private static DistributionType distribuicaoChegada;
	/** Distribuição entre chegadas poisson é exponencial. */
	private static double taxaChegada;
	/** Políica das filas.(FIFO,LIFO,LIFOFIFO) */
	private static List<QueueType> politicasFilas;
	/** Distribuição dos serviços providos por clientes vindo das filas(Determ.,Exp. e Normal)*/
	private static List<DistributionType> distribuicoesServicosFilas;
	/** Parâmetros das distribuições de serviço. */
	private static List<Double> periodosFilas;
	private static List<Double> taxasFilas;
	private static List<Double> mediasFilas;
	private static List<Double> desviosPadroesFilas;
	private static ServerType tipoServidor;
	/** Gerador de tempos de chegadas externas. */
	private static TimeGenerator geradorChegadas;
	public final static double TEMPO_MINIMO_ESTACIONARIO;
	// Uma média para saber quantos pontos semelhantes é necessário ter para dizer que a simulação atingiu estado estacionário
//	public final static int numeroDeSemelhancas = ((int) (TEMPO_MINIMO_SIMULACAO + TEMPO_MAXIMO_SIMULACAO)) / 20;
	// Um valor arbitrário de comparação entre pontos.
	public final static double porcentagemSemelhanca;
	// Valor de redução do delta x dos pontos
	public final static double reduceFactor;
	// Porcentagem de tempo da simulação em que o sistema fica estável para afirmar que ele está estável.
	public final static double porcentagemEstabilizacao;
	
	static {
		Properties prop = new Properties();
		try {
			prop.load(ParametrosSimulacao.class.getResourceAsStream("parametros.properties"));
		} catch (IOException e) {
			e.printStackTrace();
		}
		TEMPO_MINIMO_ESTACIONARIO = Double.parseDouble(prop.getProperty("TEMPO_MINIMO_ESTACIONARIO", "0.0"));
		porcentagemSemelhanca = Double.parseDouble(prop.getProperty("porcentagemSemelhanca", "0.0"));
		porcentagemEstabilizacao = Double.parseDouble(prop.getProperty("porcentagemEstabilizacao", "0.0"));
		reduceFactor = Double.parseDouble(prop.getProperty("reduceFactor", "0.0"));
	}
	
	public static DistributionType getDistribuicaoChegada() {
		return distribuicaoChegada;
	}
	public static void setDistribuicaoChegada(DistributionType distribuicaoChegada) {
		ParametrosSimulacao.distribuicaoChegada = distribuicaoChegada;
	}
	public static List<QueueType> getTiposFilas() {
		return politicasFilas;
	}
	public static void setTiposFilas(List<QueueType> politicasFilas) {
		ParametrosSimulacao.politicasFilas = new ArrayList<QueueType>(politicasFilas);
	}
	public static List<DistributionType> getDistribuicoesServicosFilas() {
		return distribuicoesServicosFilas;
	}
	public static void setDistribuicoesServicosFilas(
			List<DistributionType> distribuicoesServicosFilas) {
		ParametrosSimulacao.distribuicoesServicosFilas = new ArrayList<DistributionType>(distribuicoesServicosFilas);
	}
	public static List<Double> getPeriodosFilas() {
		return periodosFilas;
	}
	public static void setPeriodosFilas(List<Double> periodosFilas) {
		ParametrosSimulacao.periodosFilas = new ArrayList<Double>(periodosFilas);
	}
	public static List<Double> getTaxasFilas() {
		return taxasFilas;
	}
	public static void setTaxasFilas(List<Double> taxasFilas) {
		ParametrosSimulacao.taxasFilas = new ArrayList<Double>(taxasFilas);
	}
	public static List<Double> getMediasFilas() {
		return mediasFilas;
	}
	public static void setMediasFilas(List<Double> mediasFilas) {
		ParametrosSimulacao.mediasFilas = new ArrayList<Double>(mediasFilas);
	}
	public static List<Double> getDesviosPadroesFilas() {
		return desviosPadroesFilas;
	}
	public static void setDesviosPadroesFilas(List<Double> varianciasFilas) {
		ParametrosSimulacao.desviosPadroesFilas = new ArrayList<Double>(varianciasFilas);
	}
	public static int getNumeroIteracoes() {
		return numeroIteracoes;
	}
	public static void setNumeroIteracoes(int numeroIteracoes) {
		ParametrosSimulacao.numeroIteracoes = numeroIteracoes;
	}
	public static double getTaxaChegada() {
		return taxaChegada;
	}
	public static void setTaxaChegada(double taxaChegada) {
		ParametrosSimulacao.taxaChegada = taxaChegada;
	}
	public static ServerType getTipoServidor() {
		return tipoServidor;
	}
	public static void setTipoServidor(ServerType tipoServidor) {
		ParametrosSimulacao.tipoServidor = tipoServidor;
	}
	public static void setGeradorChegadas(TimeGenerator geradorChegadas) {
		ParametrosSimulacao.geradorChegadas = geradorChegadas;
	}
	public static double geraAmostraChegada(double tempoOcorrencia) {
		return ParametrosSimulacao.geradorChegadas.geraAmostra(tempoOcorrencia);
	}
	public static void resetGeradorChegada(){
		geradorChegadas.resetSeed();
	}
	public static ExecutionType getTipoExecucao() {
		return tipoExecucao;
	}
	public static void setTipoExecucao(ExecutionType tipoExecucao) {
		ParametrosSimulacao.tipoExecucao = tipoExecucao;
	}
}
